﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using ImageRecognition2.CustomControls;

using LowLevelGraphics;
using LowLevelGraphics.ColorSpaces;
using LowLevelGraphics.Types.Interval;

namespace ImageRecognition2.Forms
{
    /// <summary>
    /// Color Filter
    /// </summary>
    public partial class FormColorFilter : FormFilter
    {
        protected ByteInterval[] m_aR = null;
        protected ByteInterval[] m_aG = null;
        protected ByteInterval[] m_aB = null;

        /// <summary>
        /// Initializes a new instance of the <see cref="FormColorFilter"/> class.
        /// </summary>
        public FormColorFilter()
        {
            InitializeComponent();

            foreach (AbstractColorSpace colorspace in Definitions.ColorSpaces)
            {
                this.comboBox1.Items.Add(new ColorSpaceItem(colorspace));
            }
            InsertListBoxItem();
        }

        /// <summary>
        /// Inserts the list box item.
        /// </summary>
        private void InsertListBoxItem()
        {
            Label LabelRInterval = new Label();
            Label LabelGInterval = new Label();
            Label LabelBInterval = new Label();

            LabelRInterval.Text = "R-Int.";
            LabelRInterval.AutoSize = true;

            LabelGInterval.Text = "G-Int.";
            LabelGInterval.AutoSize = true;

            LabelBInterval.Text = "B-Int.";
            LabelBInterval.AutoSize = true;

            this.customControlListBox1.Items.Add(
                new ListBoxControlItem(
                    LabelRInterval,
                    CreateNumericUpDown(), CreateNumericUpDown(),
                    LabelGInterval,
                    CreateNumericUpDown(), CreateNumericUpDown(),
                    LabelBInterval,
                    CreateNumericUpDown(), CreateNumericUpDown()));
        }

        /// <summary>
        /// Creates the numeric up down.
        /// </summary>
        /// <returns></returns>
        private NumericUpDown CreateNumericUpDown()
        {
            return CreateNumericUpDown(0, 255);
        }

        /// <summary>
        /// Creates the numeric up down.
        /// </summary>
        /// <returns></returns>
        private NumericUpDown CreateNumericUpDown(int _nMin, int _nMax)
        {
            NumericUpDown nud = new NumericUpDown();
            nud.Minimum = _nMin;
            nud.Maximum = _nMax;
            nud.ValueChanged += new EventHandler(nud_ValueChanged);
            return nud;
        }

        /// <summary>
        /// Handles the ValueChanged event of the nud control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        void nud_ValueChanged(object sender, EventArgs e)
        {
            CreateRangeIntervals();
            Bitmap formFilterpictureBox1BackgroundImageClone = (Bitmap)this.m_ImageOriginal.Clone();
            //new SingleLayerMultiThreshold(this.R, this.G, this.B).Execute(formFilterpictureBox1BackgroundImageClone).Dispose();
            this.pictureBox1.BackgroundImage = formFilterpictureBox1BackgroundImageClone;
        }

        /// <summary>
        /// Gets the R.
        /// </summary>
        /// <value>The R.</value>
        public ByteInterval[] R
        {
            get { return m_aG; }
        }

        /// <summary>
        /// Gets the G.
        /// </summary>
        /// <value>The G.</value>
        public ByteInterval[] G
        {
            get { return m_aR; }
        }

        /// <summary>
        /// Gets the B.
        /// </summary>
        /// <value>The B.</value>
        public ByteInterval[] B
        {
            get { return m_aB; }
        }

        private void addRangeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            InsertListBoxItem();
        }

        /// <summary>
        /// Handles the Click event of the cbAddRange control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void cbAddRange_Click(object sender, EventArgs e)
        {
            InsertListBoxItem();
        }

        /// <summary>
        /// Handles the Click event of the cbDeleteRange control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void cbDeleteRange_Click(object sender, EventArgs e)
        {
            RemoveItem();
        }

        /// <summary>
        /// Handles the Click event of the cbClear control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void cbClear_Click(object sender, EventArgs e)
        {
            this.customControlListBox1.Items.Clear();
        }

        /// <summary>
        /// Handles the Click event of the clearToolStripMenuItem control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void clearToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.customControlListBox1.Items.Clear();
        }

        /// <summary>
        /// Removes the item.
        /// </summary>
        private void RemoveItem()
        {
            ListBoxControlItem item = this.customControlListBox1.SelectedItem as ListBoxControlItem;
            if (item != null)
            {
                this.customControlListBox1.Items.Remove(item);
            }
        }

        /// <summary>
        /// Creates the range intervals.
        /// </summary>
        protected void CreateRangeIntervals()
        {
            int nCount = this.customControlListBox1.Items.Count;
            m_aR = new ByteInterval[nCount];
            m_aG = new ByteInterval[nCount];
            m_aB = new ByteInterval[nCount];

            int nIndex = 0;
            foreach (ListBoxControlItem item in this.customControlListBox1.Items)
            {
                List<NumericUpDown> aNud = new List<NumericUpDown>();
                foreach (Control control in item.Controls)
                {
                    NumericUpDown nud = control as NumericUpDown;
                    if (nud == null) continue;
                    aNud.Add(nud);
                }
                m_aR[nIndex] = new ByteInterval((byte)aNud[0].Minimum, (byte)aNud[1].Maximum);
                m_aG[nIndex] = new ByteInterval((byte)aNud[2].Minimum, (byte)aNud[3].Maximum);
                m_aB[nIndex] = new ByteInterval((byte)aNud[4].Minimum, (byte)aNud[5].Maximum);
                nIndex++;
            }
        }
    }

    /// <summary>
    /// 
    /// </summary>
    public class ColorSpaceItem
    {
        protected AbstractColorSpace m_AbstractColorSpace = null;

        /// <summary>
        /// Initializes a new instance of the <see cref="ColorSpaceItem"/> class.
        /// </summary>
        /// <param name="_abstractColorSpace">The _abstract color space.</param>
        public ColorSpaceItem(AbstractColorSpace _abstractColorSpace)
        {
            m_AbstractColorSpace = _abstractColorSpace;
        }

        /// <summary>
        /// Gets the color space.
        /// </summary>
        /// <value>The color space.</value>
        public AbstractColorSpace ColorSpace
        {
            get { return m_AbstractColorSpace; }
        }

        /// <summary>
        /// Returns a <see cref="System.String"/> that represents this instance.
        /// </summary>
        /// <returns>
        /// A <see cref="System.String"/> that represents this instance.
        /// </returns>
        public override string ToString()
        {
            return m_AbstractColorSpace.Name;
        }
    }
}
